package com.chianghao.rockframewrok.core.generator;

import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.chianghao.rockframewrok.core.db.model.Table;
import com.chianghao.rockframewrok.core.generator.template_model.ControllerModel;
import com.chianghao.rockframewrok.core.generator.template_model.PojoModel;
import com.chianghao.rockframewrok.core.generator.template_model.PropertyModel;
import com.chianghao.rockframewrok.core.utils.FileUtils;
import com.chianghao.rockframewrok.core.utils.StringUtils;

import freemarker.template.Template;

public class Generator {

	
	/**
	 * 生成代码到指定的目录 
	 * @param outDic        输出目录
	 */
	public static void doGen(String outDic) {
		File root = new File(outDic);
		if(root.exists()) {
			root.delete();
		}
		try {
			root.mkdir();
		}catch(Exception e) {
			//e.getSuppressed();
		}
		
		Map<String,Table> eMap = Table.getTableMap();
		for(Table table:eMap.values()) {
			String packagePrefix="";
			File outDicFile = root;
			String[] packageArray  = table.getClazz().getName().split("\\."); 
			
			String projectName = null;
			
			for(int i=0;i<(packageArray.length-2);i++) {
				outDicFile  = new File(outDicFile,packageArray[i]);
				if(!outDicFile.exists()) {
					outDicFile.mkdir();
				}
				if(i==0) {
					packagePrefix += packageArray[i];
				}else {
					packagePrefix +="."+packageArray[i];
				}
				projectName = packageArray[i];
			}
			
			File daoDicFile  = new File(outDicFile,"dao");
			if(!daoDicFile.exists()) {
				daoDicFile.mkdir();
			}
			String daoPackage = packagePrefix+".dao";
			
			File serviceDicFile = new File(outDicFile,"service");
			if(!serviceDicFile.exists()) {
				serviceDicFile.mkdir();
			}
			String servicePackage = packagePrefix+".service";
			
			File controllerDicFile = new File(outDicFile,"controller");
			if(!controllerDicFile.exists()) {
				controllerDicFile.mkdir();
			}
			String controllerPackage = packagePrefix+".controller";
			
			
			
			//生成dao文件
			String itemName = StringUtils.camelToUnderline(table.getObjectName());
		    File itemDaoDicFile = new File(daoDicFile,itemName);
		    if(!itemDaoDicFile.exists()) {
		    	itemDaoDicFile.mkdir();
		    }
		    String itemDaoPackage = daoPackage+"."+itemName;
		    //----构建Mapper接口
		    String interfaceClassSimpleName = table.getObjectName()+"Mapper";
		    String interfaceClassName = itemDaoPackage+"."+interfaceClassSimpleName;
		    String mapperContent = String.format(mapperInterfaceString, 
		    		itemDaoPackage,
		    		table.getClazz().getName(),
		    		interfaceClassSimpleName,
		    		table.getObjectName()
		    		);
		    FileUtils.write(new File(itemDaoDicFile,interfaceClassSimpleName+".java"), mapperContent);
		    //----构建Mapper.xml文件
		    String mapperXMlContent = String.format(mapperXmlString, interfaceClassName);
		    FileUtils.write(new File(itemDaoDicFile,interfaceClassSimpleName+".xml"), mapperXMlContent);
		    
		    
			//生成server文件
		    String itemServicePackage = servicePackage+"."+itemName;
		    String serviceClassSimplateName  = table.getObjectName()+"Service";
		    String serviceClassName   = itemServicePackage+"."+serviceClassSimplateName;
		    String serviceContent  = String.format(serviceString, 
		    		itemServicePackage,
		    		table.getClazz().getName(),
		    		interfaceClassName,
		    		serviceClassSimplateName,
		    		interfaceClassSimpleName,
		    		table.getObjectName()
		    		);
		    
		    File itemServiceDicFile = new File(serviceDicFile,itemName);
		    if(!itemServiceDicFile.exists()) {
		    	itemServiceDicFile.mkdir();
		    }
		    FileUtils.write(new File(itemServiceDicFile,serviceClassSimplateName+".java"), serviceContent);
		    
		    
		    List<PropertyModel> propertyModels = new ArrayList<PropertyModel>();
		    for(Field field:table.getFieldMap().values()) {
		    	String propertyClassSimpleName=field.getType().getName();
		    	String fieldName=StringUtils.firstCharLowercase(field.getName());
		    	String getMethodName="get"+StringUtils.firstCharUpperCase(field.getName());
		    	String setMethodName="set"+StringUtils.firstCharUpperCase(field.getName());
		    	
		    	if(Boolean.class.isAssignableFrom(field.getType())||boolean.class.isAssignableFrom(field.getType())) {
		    		getMethodName="is"+StringUtils.firstCharUpperCase(field.getName());
		    	}
		    	
		    	PropertyModel p  = new PropertyModel(propertyClassSimpleName,fieldName,getMethodName,setMethodName);
		    	propertyModels.add(p);
		    }
		    


		    //----拼写controller层的代码
		    File itemControllerDicFile = new File(controllerDicFile,itemName);
		    if(!itemControllerDicFile.exists()) {
		    	itemControllerDicFile.mkdir();
		    }
		    
		    
		    String itemControllerPackage = controllerPackage+"."+itemName;
		    String controllerClassSimplateName  = table.getObjectName()+"Controller";
		    //String controllerClassName   = itemControllerPackage+"."+controllerClassSimplateName;
		    
		    
		    //------------拼写DTO
		    String itemControllerDtoPackage = itemControllerPackage+".dto";
		    String entityDtoClassSimpleName=table.getObjectName()+"Dto";
		    String entityDtoClassName=itemControllerDtoPackage+"."+entityDtoClassSimpleName;
		    File itemControllerDtoDicFile = new File(itemControllerDicFile,"dto");
		    if(!itemControllerDtoDicFile.exists()) {
		    	itemControllerDtoDicFile.mkdir();
		    }
		    PojoModel dtoPojo = new PojoModel();
		    dtoPojo.setEntityClassSimpleName(table.getObjectName());
		    dtoPojo.setPackageName(itemControllerDtoPackage);
		    dtoPojo.setProperties(propertyModels);
		    writeFile("dto.ftl",new File(itemControllerDtoDicFile,entityDtoClassSimpleName+".java"),dtoPojo);
		    //------------拼写DTO
		    
		    //------------拼写vo
		    String inteControllerVoPackage  = itemControllerPackage+".vo";
		    String entityVoClassSimpleName=table.getObjectName()+"Vo";
			String entityVoClassName=inteControllerVoPackage+"."+entityVoClassSimpleName;
			
			File itemControllerVoDicFile = new File(itemControllerDicFile,"vo");
		    if(!itemControllerVoDicFile.exists()) {
		    	itemControllerVoDicFile.mkdir();
		    }
		    
		    PojoModel voPojo = new PojoModel();
		    voPojo.setEntityClassSimpleName(table.getObjectName());
		    voPojo.setPackageName(inteControllerVoPackage);
		    voPojo.setProperties(propertyModels);
		    
		    writeFile("vo.ftl",new File(itemControllerVoDicFile,entityVoClassSimpleName+".java"),voPojo);
		    //------------拼写vo
			
			String entityClassName=table.getClazz().getName();
			String entityClassSimpleName=table.getObjectName();
			String entityObjectName=StringUtils.firstCharLowercase(entityClassSimpleName);
			
			String entityServiceClassName=serviceClassName;
			String entityServiceClassSimpleName=serviceClassSimplateName;
			String entityServiceObjectName=StringUtils.firstCharLowercase(serviceClassSimplateName);
			String controllerRootPath=projectName+"/"+itemName;
		    
			//生成controller文件
		    ControllerModel controllerModel = new ControllerModel(
		    		itemControllerPackage,
		    		entityDtoClassName,
		 			entityDtoClassSimpleName,
		 			entityVoClassName,
		 			entityClassName,
		 			entityClassSimpleName,
		 			entityObjectName,
		 			entityServiceClassName,
		 			entityServiceClassSimpleName,
		 			entityServiceObjectName,
		 			controllerRootPath
		    );
		    
		    File controllerFile  =  new File(itemControllerDicFile,controllerClassSimplateName+".java");
		    writeFile("controller.ftl",controllerFile,controllerModel);
		}
	}
	
	
	private static void writeFile(String ftl,File tagFile,Object model) {
		Template temp = null;
	    try {
	    	temp = FreeMarkerConfig.get().getTemplate(ftl);
		} catch (Exception e) {
			System.out.println("==========获取freemarker模板错误=========");
			e.printStackTrace();
		} 
	    if(temp!=null) {
	    	try {
	    		FileWriter out = new FileWriter(tagFile);
	    		temp.process(model, out);
	    	}catch(Exception e) {
	    		System.out.println("==========freemarker写出错误=========");
	    		e.printStackTrace();
	    	}
	    	
	    }
	}
	
	
	private final static String mapperInterfaceString="package %s;\r\n" + 
			"\r\n" + 
			"import %s;\r\n" + 
			"\r\n" + 
			"import chianghao.core.mybatis.mapper.BaseMapper;\r\n" + 
			"\r\n" + 
			"public interface %s extends BaseMapper<%s> {\r\n" + 
			"\r\n" + 
			"}";
	private final static String mapperXmlString="<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\r\n" + 
			"<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\" >\r\n" + 
			"<mapper namespace=\"%s\">\r\n" + 
			"\r\n" + 
			"\r\n" + 
			"</mapper>";
	
	
	private final static String serviceString="package %s;\r\n" + 
			"\r\n" + 
			"import chianghao.core.frame.service.BaseService;\r\n" + 
			"import org.springframework.stereotype.Service;\r\n" + 
			"import %s;\r\n" + 
			"import %s;\r\n" + 
			"\r\n" +
			"@Service\r\n"+
			"public class %s extends BaseService<%s, %s> {\r\n" + 
			"\r\n" + 
			"\r\n" + 
			"\r\n" + 
			"\r\n" + 
			"}";
	
	
}
